package com.loto.insurance.mis.web.controller.ajax;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.loto.insurance.mis.web.authority.INSAuthority;
import com.loto.insurance.mis.web.entity.ajax.BaseJson;
import com.loto.insurance.mis.web.entity.ajax.CustFeeFlow;
import com.loto.insurance.mis.web.entity.ajax.GridJson;
import com.loto.insurance.mis.web.enumeration.ControllerPropertyEnum;
import com.loto.insurance.mis.web.enumeration.FeeTypeEnum;
import com.loto.insurance.mis.web.enumeration.MenuEnum;
import com.loto.insurance.mis.web.enumeration.PayChannelEnum;
import com.loto.insurance.mis.web.enumeration.PayForEnum;
import com.loto.insurance.mis.web.enumeration.PaymentStatusEnum;
import com.loto.insurance.mis.web.enumeration.ResultTypeEnum;
import com.loto.insurance.mis.web.service.CustFeeFlowService;
import com.loto.insurance.mis.web.service.CustInfoService;
import com.loto.insurance.mis.web.service.OemService;
import com.loto.insurance.mis.web.entity.CustInfo;
import com.loto.insurance.mis.web.entity.OemInfo;
import com.loto.insurance.mis.web.entity.Pager;
import com.loto.utils.DateUtils;
import com.loto.utils.Http;
import com.loto.utils.XML;

@Controller
@SessionAttributes("ins_user")
public class FinancialJsonController {
  static Logger logger = LogManager.getLogger(FinancialJsonController.class);

  @Autowired
  CustFeeFlowService custFeeFlowService;

  @Autowired
  CustInfoService custInfoService;

  @Autowired
  OemService oemService;

  @INSAuthority(authorityMenu = MenuEnum.PRODUCT_LIST, resultType = ResultTypeEnum.json)
  @RequestMapping(value = "/financial/feelist.json", method = RequestMethod.POST)
  public ModelAndView productList(
	  @RequestParam(value = "name", required = false) String name,
	  @RequestParam(value = "tno", required = false) String tno,
	  @RequestParam(value = "begin", required = false) String begin,
	  @RequestParam(value = "ono", required = false) String ono,
	  @RequestParam(value = "end", required = false) String end,
	  @RequestParam(value = "channel", required = false) String channel,
	  @RequestParam(value = "feeType", required = false, defaultValue = "-1") int feeType,
	  @RequestParam(value = "page", required = false, defaultValue = "1") int page,
	  @RequestParam(value = "rows", required = false, defaultValue = "20") int rows) {
	Map<String, Object> params = new HashMap<String, Object>();
	if (name != null && !name.isEmpty())
	  params.put("name", name);
	if (tno != null && !tno.isEmpty())
	  params.put("tno", tno);
	if (ono != null && !ono.isEmpty())
	  params.put("ono", ono);
	if (begin != null && end != null && DateUtils.isDate(begin, "yyyy-MM-dd")
	    && DateUtils.isDate(end, "yyyy-MM-dd")) {
	  params.put("begin", begin);
	  params.put("end", end);
	}
	if (channel != null && !channel.isEmpty())
	  params.put("channel", channel);
	if (feeType > -1)
	  params.put("feeType", feeType);

	Pager pager = new Pager();
	pager.setPageSize(rows);

	params.put("pageSize", pager.getPageSize());
	params.put("startIndex", pager.getPageSize() * (page - 1));

	if (page > 1)
	  pager.setIndex(page);
	List<com.loto.insurance.mis.web.entity.CustFeeFlow> flowList = custFeeFlowService
	    .findAllFeeFlow(params);

	ArrayList<CustFeeFlow> list = new ArrayList<CustFeeFlow>();
	for (com.loto.insurance.mis.web.entity.CustFeeFlow flow : flowList) {
	  CustFeeFlow f = new CustFeeFlow();
	  f.setCustName(flow.getCustName());
	  f.setFlowChangedFee(flow.getFlowChangedFee());
	  f.setFlowChannel(flow.getFlowChannel());
	  f.setFlowId(flow.getFlowId());
	  f.setFlowMemo(flow.getFlowMemo());
	  f.setFlowPaidOn(DateUtils.formatShortDateTime(flow.getFlowPaidOn()));
	  f.setFlowPayNo(flow.getFlowPayNo());
	  f.setFlowRoyaltyFee(flow.getFlowRoyaltyFee());
	  f.setFlowRoyaltyPayee(flow.getFlowRoyaltyPayee());

	  int flowType = flow.getFlowType();
	  for (FeeTypeEnum fe : FeeTypeEnum.values()) {
		if (fe.getIndex() == flowType) {
		  f.setFlowType(fe.getName());
		  break;
		}
	  }

	  list.add(f);
	}

	pager.setRowCount(custFeeFlowService.findAllFeeFlowCount(params));

	ModelAndView mav = new ModelAndView();

	GridJson<CustFeeFlow> gridJson = new GridJson<CustFeeFlow>();
	gridJson.setTotal(pager.getRowCount());
	gridJson.setRows(list);

	mav.addObject("result", gridJson);
	return mav;
  }

  @INSAuthority(authorityMenu = MenuEnum.FINANCIAL_FEE_LIST, resultType = ResultTypeEnum.json)
  @RequestMapping(value = "/financial/feeadjust.json", method = RequestMethod.POST)
  public ModelAndView feeadjust(@RequestParam(value = "name") String name,
	  @RequestParam(value = "type") int type,
	  @RequestParam(value = "fee") BigDecimal fee,
	  @RequestParam(value = "no") String no,
	  @RequestParam(value = "memo") String memo) {
	BaseJson baseJson = new BaseJson();
	baseJson.setOk(false);

	CustInfo custInfo = custInfoService.findByName(name);
	if (custInfo != null) {
	  UUID uuid = UUID.randomUUID();
	  String uid = uuid.toString().replace("-", "");
	  boolean canUpdated = false;
	  Calendar now = Calendar.getInstance();

	  List<com.loto.insurance.mis.web.entity.OemInfo> oemList = oemService
		  .findOemByCustId(custInfo.getCustId());
	  if (oemList != null && oemList.size() == 1) {
		OemInfo oemInfo = oemList.get(0);
		// 获取OEM余额
		BigDecimal oemUsefulfee = custInfoService.getOemAdminFee(oemInfo);
		if (oemUsefulfee.add(fee).compareTo(new BigDecimal(0)) >= 0) {
		  // TODO 通知OEM更新
		  com.loto.insurance.mis.web.entity.service.CustFeeFlow serviceFeeFlow = new com.loto.insurance.mis.web.entity.service.CustFeeFlow();
		  serviceFeeFlow.setFlowAfterFee(oemUsefulfee.add(fee));
		  serviceFeeFlow.setFlowBeforeFee(oemUsefulfee);
		  serviceFeeFlow.setFlowChangedFee(fee);
		  serviceFeeFlow.setFlowChannel(PayChannelEnum.BALANCE.getName());
		  serviceFeeFlow.setFlowFlag(PaymentStatusEnum.SUC.getIndex());
		  serviceFeeFlow.setFlowFor(PayForEnum.SUPPLEMENT.getIndex());
		  serviceFeeFlow.setFlowMemo(memo);
		  serviceFeeFlow.setFlowPayNo(no);
		  serviceFeeFlow.setFlowOutPayNo(no);
		  serviceFeeFlow.setFlowPlatformId(uid);
		  serviceFeeFlow.setFlowRelatedFid(0);
		  serviceFeeFlow.setFlowType(type);
		  Map<String, String> paramMap = new HashMap<String, String>();
		  paramMap.put("acc", oemInfo.getOemAcc());
		  paramMap.put("pin", oemInfo.getOemPin());
		  paramMap.put("content", XML.toXML(serviceFeeFlow,
			  com.loto.insurance.mis.web.entity.service.CustFeeFlow.class));
		  try {
			String xmlResponse = Http.doPost("http://" + oemInfo.getOemDomain()
			    + "/webservice/adjustadminfee.service", paramMap);
			logger.info(xmlResponse);
			BaseJson response = XML.fromXML(xmlResponse, BaseJson.class);
			if (response == null || !response.isOk()) {
			  logger.error("通知OEM更新admin余额[" + oemInfo.getOemId() + "-"
				  + oemInfo.getOemName() + "]失败");
			} else {
			  logger.info("通知OEM更新admin余额[" + oemInfo.getOemId() + "-"
				  + oemInfo.getOemName() + "]成功：" + response.getMsg());
			  canUpdated = true;
			}
		  } catch (Exception ex) {
			ex.printStackTrace();
			logger.error("通知OEM更新admin余额[" + oemInfo.getOemId() + "-"
			    + oemInfo.getOemName() + "]失败");
		  }
		} else {
		  baseJson.setMsg(ControllerPropertyEnum.OEM_LESS_USEFULFEE.toString());
		}
	  } else {
		canUpdated = true;
	  }
	  if (canUpdated) {
		com.loto.insurance.mis.web.entity.CustFeeFlow feeFlow = new com.loto.insurance.mis.web.entity.CustFeeFlow();
		feeFlow.setFlowChangedFee(fee);
		feeFlow.setFlowChannel(PayChannelEnum.BALANCE.getName());
		feeFlow.setFlowPaidOn(now.getTime());
		feeFlow.setFlowCustFid(custInfo.getCustId());
		feeFlow.setFlowSubCustFid(0);
		feeFlow.setFlowFlag(PaymentStatusEnum.SUC.getIndex());
		feeFlow.setFlowFor(PayForEnum.SUPPLEMENT.getIndex());
		feeFlow.setFlowRelatedFid(0);
		feeFlow.setFlowMemo(memo);
		feeFlow.setFlowOutPayNo(no);
		feeFlow.setFlowPayNo(no);
		feeFlow.setFlowType(type);
		feeFlow.setFlowOutPayDesc("");
		feeFlow.setFlowOutPayNo("");
		feeFlow.setFlowPayFee(fee);
		feeFlow.setFlowPlatformId(uid);
		feeFlow.setFlowRoyaltyFee(new BigDecimal(0));
		feeFlow.setFlowRoyaltyMemo("");
		feeFlow.setFlowRoyaltyPayee("");
		feeFlow.setFlowRoyaltyPayer("");
		if (custInfoService.adjustFee(feeFlow)) {
		  baseJson.setOk(true);
		}
	  }
	} else {
	  baseJson.setMsg(ControllerPropertyEnum.CUST_NOT_EXISTED.toString());
	}
	ModelAndView mav = new ModelAndView();
	mav.addObject("result", baseJson);
	return mav;
  }

  @INSAuthority(authorityMenu = MenuEnum.FINANCIAL_FEE_LIST, resultType = ResultTypeEnum.json)
  @RequestMapping(value = "/financial/feequery.json", method = RequestMethod.POST)
  public ModelAndView feeadjust(@RequestParam(value = "name") String name) {
	BaseJson baseJson = new BaseJson();
	baseJson.setOk(false);

	CustInfo custInfo = custInfoService.findByName(name);
	if (custInfo != null) {
	  List<com.loto.insurance.mis.web.entity.OemInfo> oemList = oemService
		  .findOemByCustId(custInfo.getCustId());
	  if (oemList != null && oemList.size() == 1) {
		String oemUsefulfee = "0";
		// 获取OEM余额
		oemUsefulfee = String.valueOf(custInfoService.getOemAdminFee(oemList
		    .get(0)));

		baseJson.setMsg(custInfo.getCustUsefulFee() + "|1|" + oemUsefulfee);
	  } else {
		baseJson.setMsg(custInfo.getCustUsefulFee() + "|0|0");
	  }
	  baseJson.setOk(true);

	} else {
	  baseJson.setMsg(ControllerPropertyEnum.CUST_NOT_EXISTED.toString());
	}
	ModelAndView mav = new ModelAndView();
	mav.addObject("result", baseJson);
	return mav;
  }
}
